#include <signal.h>

#include <vector>
#include <iostream>
#include <string>

#include <workflow/WFFacilities.h>
#include <workflow/WFTaskFactory.h>
#include <workflow/HttpUtil.h>

using std::cout;
using std::endl;
using std::vector;
using std::string;

static WFFacilities::WaitGroup waitGroup(1);

void sighandler(int num)
{
    cout << "sighandler is processing" << endl;
    waitGroup.done();
}

struct SeriesContext
{
    string url;
    int state;
    int error;
    protocol::HttpResponse resp;
};

void httpCallback(WFHttpTask * httpTask);

void httpSeriesCallback(const SeriesWork * );

void parallelCallback(const ParallelWork * );

void seriesCallback(const SeriesWork *);


void test0()
{
    signal(SIGINT, sighandler);

    vector<string> webs {
        //"http://www.baidu.com",
        "http://localhost:8082",
        "http://localhost:8080",
        "http://localhost:8081"
    };

    //1. 创建并行任务
    auto parallelWork = Workflow::create_parallel_work(parallelCallback);

    //2. 创建任务并添加到并行任务中
    for(size_t i = 0; i < webs.size(); ++i) {
        //创建HttpTask
        auto httpTask = WFTaskFactory::create_http_task(
            webs[i], 0, 0, httpCallback);
        httpTask->get_req()->add_header_pair("User-Agent", "Workflow Client");
        httpTask->get_req()->add_header_pair("Accept", "*/*");

        //创建序列
        auto series = Workflow::create_series_work(httpTask, httpSeriesCallback);
        //设置每一个序列的context
        auto context = new SeriesContext;
        context->url = webs[i];//只能存储url信息
        series->set_context(context);//其他的信息都需要在任务的回调函数中获取
        parallelWork->add_series(series);
    }

    //3. 在一个序列之中去运行并行任务
    Workflow::start_series_work(parallelWork, seriesCallback);

    waitGroup.wait();
}


int main()
{
    test0();
    return 0;
}

void httpCallback(WFHttpTask * httpTask)
{
    //cout << "httpTask callback is running" << endl;
    auto req = httpTask->get_req();
    auto resp = httpTask->get_resp();
    auto context = (SeriesContext*)series_of(httpTask)->get_context();
    context->state = httpTask->get_state();
    context->error = httpTask->get_error();
    context->resp = std::move(*resp);//对于消息不能复制,只能转移

    cout << context->url << endl;

}

void httpSeriesCallback(const SeriesWork * )
{
    cout << "httpSeries callback is running" << endl;
}

void parallelCallback(const ParallelWork * parallelWork)
{
    cout << "parallel task callback is running" << endl;
    size_t sz = parallelWork->size();
    cout << ">> sz:" << sz << endl;
    for(size_t i = 0; i < sz; ++i) {
        //在并行任务中获取序列，使用的是series_at方法
        auto context = (SeriesContext*)parallelWork->series_at(i)->get_context();
        if(context->state == WFT_STATE_SUCCESS) {
            cout << "reqest url:" << context->url << endl;
            const void * body;
            size_t size = 0;
            context->resp.get_parsed_body(&body,&size);
            printf("%s\n\n", (char*)body);
        } else {
            printf("Error:%s\n",
                WFGlobal::get_error_string(context->state, context->error));
        }

        delete context;//回收每一个序列的context
    }
}

void seriesCallback(const SeriesWork *)
{
    cout << "series of parallel task callback is running" << endl;
    waitGroup.done();
}
